package Webcrawler;

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter a word: ");
        String word = sc.nextLine();
        System.out.print("Enter a URL: ");
        String url = sc.nextLine();
        crawler(word, url);
        sc.close();
    }

    public static void crawler(String word, String startingURL) {
        ArrayList<String> listOfPendingURLs = new ArrayList<>(); //存放待处理的地址
        ArrayList<String> listOfTraversedURLs = new ArrayList<>(); //存放已处理的地址

        listOfPendingURLs.add(startingURL); //把通过参数传进的地址存进动态数组，以进入循环
        while (!listOfPendingURLs.isEmpty() && listOfTraversedURLs.size() <= 100) { //【待处理地址的数组】为空或者【已处理地址的数组】元素超过100个则结束循环
            String urlString = listOfPendingURLs.remove(0); //每次弹出并处理数组中第1个地址
            if (!listOfTraversedURLs.contains(urlString)) { //如果地址已经被处理过（存在于【已处理地址的数组】中），则不需要重复进行
                listOfTraversedURLs.add(urlString); //把【未处理过的地址】放进【已处理地址的数组】中，然后进行处理
                System.out.println("Crawl " + urlString);

                if (in(word, urlString)) { //找到了指定的字符串，输出该网址并退出整个程序
                    System.out.print("the URL which you need: ");
                    System.out.println(urlString);
                    return;
                }

                for (String s : getSubURLs(urlString)) { //未在当前页面找到指定的字符串，把当前页面下所有【未处理过的地址】放进【待处理地址的数组】中
                    if (!listOfPendingURLs.contains(s)) { //已经处理过，则不需要放入
                        listOfPendingURLs.add(s);
                    }
                }
            }
        }

        System.out.printf("Sorry, %s has not been found!\n", word); //前面的过程全部进行完毕，但还没有找到
    }

    public static ArrayList<String> getSubURLs(String urlString) { //返回【当前页面中子地址的数组】
        ArrayList<String> list = new ArrayList<>();

        try {
            java.net.URL url = new java.net.URL(urlString); //把【传入的地址字符串】转换为【计算机可以识别的链接】
            Scanner input = new Scanner(url.openStream()); //把当前链接指向页面的源代码放进input中
            int current = 0; //current代表【指定字符串】在【当前行首次出现的位置】，初始值任意
            while (input.hasNext()) {
                String line = input.nextLine(); //逐行处理，考虑到https和http可能一起出现，这里把原先的【:】删掉了
                current = line.indexOf("http", current); //从current开始找，如果找不到，current就变成-1
                while (current > 0) {
                    int endIndex = line.indexOf("\"", current); //【\"】代表【"】，是【http开头地址】结尾后的第1个字符
                    if (endIndex > 0) { //确认找到的字符串的确是地址（以【"】结尾）
                        list.add(line.substring(current, endIndex)); //截取该行中刚找到的地址，存入数组
                        current = line.indexOf("http", endIndex); //再从endIndex开始找，看看【刚放入数组的地址】后面还有没有http
                    } else { //若找到的字符串不是地址，则把-1赋给current，以结束循环
                        current = -1;
                    }
                }
            }
        } catch (Exception ex) { //捕获并输出异常，让程序得以正常进行
            System.out.println("Error: " + ex.getMessage());
        }

        return list; //返回得到的数组（存放当前页面中所有的地址）
    }

    static boolean in(String word, String urlString) {
        try {
            java.net.URL url = new java.net.URL(urlString);
            Scanner input = new Scanner(url.openStream()); //把当前页面源代码存进input
            while (input.hasNext()) {
                String line = input.nextLine();//逐行寻找指定字符串
                int index = line.indexOf(word);
                if (index >= 0) {
                    input.close();
                    return true;
                }
            }
        } catch (Exception ex) {
            System.out.println("Error: " + ex.getMessage());
        }
        return false; //到最后都没找到，则返回false
    }
}